$(function () {
    $(".dialog").bind("dialogcreate", function () {
        var dialog = $(this);
        var uiDialog = $(this).parent();

        uiDialog.keyup(function (event) {
            if (event.keyCode == $.ui.keyCode.ESCAPE) {
                dialog.data("fnClose").call(dialog);
            }

            if (event.keyCode == $.ui.keyCode.ENTER && event.target.tagName.toLowerCase() !== "button") {
                dialog.data("fnOk").call(dialog);
            }
        });

        uiDialog.find(".ui-dialog-titlebar-close").click(function (event) {
            dialog.data("fnClose").call(dialog);
        });

    });

    $(".dialog").bind("dialogopen", function () {
        var uiDialog = $(this).parent();

        uiDialog.find(".ui-button").addClass("dialog-button");

        //Set focus on button if necessary
        if (!$(this).hasClass("focusOnInput")) {
            uiDialog.find(".ui-button[defaultbutton=true]").focus();
        }

        $(".dialog-button").keyup(function (event) {
            if (event.keyCode == $.ui.keyCode.LEFT || event.keyCode == $.ui.keyCode.RIGHT) {
                $(".dialog-button").not($(this)).focus();
            }
        });
    });

    $("button").button();

    $("input.calendar").datepicker({
        showOn:"button",
        buttonImageOnly:true,
        buttonImage:"images/calendar.gif",
        dateFormat:"yy-mm-dd",
        firstDay:1
    });


    $("#pageMenu .menu").hover(function () {
        $(this).toggleClass("selected");
        $("select").blur();
    }, function () {
        $(this).toggleClass("selected");
    });

    $(".button-panel").each(function () {
        var $this = $(this);
        var $rightPanel = $("<div class='right-button-panel'></div>");

        $this.append($rightPanel);
        $rightPanel.append($this.children("button"))
    });

    $(".menuitems").bgiframe();

});

function showAlertDialog($element, fnClose, width, height) {
    var tabsTuple = {
        index:0,
        tabables:[]
    };

    if (!fnClose) {
        fnClose = defaultCloseFunction();
    }

    if (!$element.data("fnClose")) {
        $element.data("fnClose", fnClose);
    }

    function switchByTab(e) {
        if (tabsTuple.tabables.length == 0) {
            tabsTuple.tabables = $(':tabbable', $("div.ui-dialog-buttonpane:parent").parent());
        }

        tabCarousel(e, tabsTuple);
    }

    var option = {
        open:function () {
            switchTabHook(true, switchByTab);
        },
        close:function () {
            switchTabHook(false, switchByTab);
        },
        autoOpen:true,
        closeOnEscape:false,
        modal:true,
        width:width,
        height:height,
        buttons:[createButton(i18n.dialog.OK, fnClose, 0)]
    };

    $element.dialog(option);

}

/**
 * Show confirm dialog
 *
 * @param $element {Element} dialog's element
 * @param fnOk {function} function that acts on OK clicking
 * @param fnClose {?function()} it invokes when dialog's CANCEL button was pressed
 * @param isOkDefault {boolean}
 * @param {function=} fnCleanUp function that will be called on dialog closing.
 *  Sometimes you may need to clean-up something after dialog closing (free some data arrays, remove some DOM nodes etc.)
 */
function showConfirmDialog($element, fnOk, fnClose, isOkDefault, fnCleanUp) {
    var tabsTuple = {
        index:0,
        tabables:[]
    };

    if (!fnClose) {
        fnClose = defaultCloseFunction();
    }

    if (!$element.data("fnOk")) {
        $element.data("fnOk", fnOk);
    }

    if (!$element.data("fnClose")) {
        $element.data("fnClose", fnClose);
    }

    function switchByTab(e) {
        if (tabsTuple.tabables.length == 0) {
            tabsTuple.tabables = $(':tabbable', $("div.ui-dialog-buttonpane:parent").parent());
        }

        tabCarousel(e, tabsTuple);
    }

    var options = {
        open:function () {
            switchTabHook(true, switchByTab);
        },
        close:function () {
            switchTabHook(false, switchByTab);

            if (fnCleanUp !== undefined) {
                fnCleanUp.call(this);
            }
        },
        autoOpen:true,
        closeOnEscape:false,
        modal:true,
        resizable:false,
        width:200,
        buttons:[createButton(i18n.dialog.CONFIRM, fnOk, isOkDefault), createButton(i18n.dialog.cancel, fnClose, !isOkDefault)]
    };

    $element.dialog(options);
}

function createButton(label, fn, isDefault) {
    return {text:label, click:fn, defaultbutton:isDefault ? true : false};
}

function defaultCloseFunction() {
    return function () {
        $(this).dialog("close");
    };
}

// <Tab button utils>
var tabCarousel = function (e, tuple) {
    if (e.keyCode == $.ui.keyCode.TAB) {
        if (tuple.index == tuple.tabables.length) {
            tuple.index = 0;
        }

        tuple.tabables[tuple.index++].focus();

        e.preventDefault();
    }
};

var switchTabHook = function (enable, fn) {
    if (enable) {
        $(window.document).bind('keydown', fn);
    } else {
        $(window.document).unbind('keydown', fn);
    }
};
// </Tab button utils>

UI = {
    /**
     * Show 'nodata' i18n-ed string in case if data is null or undefined
     *
     * @param data
     */
    norm:function (data) {
        return (data === undefined || data == null) ? i18n.general.noData : data
    },

    /**
     * Example: 'This is a {?}'  (where {?} is 'cat')
     * Will be output: 'This is a cat'
     *
     * @param label
     * @param params
     */
    format:function (label, params) {
        var i = 0;

        if (!$.isArray(params)) {
            var p = params;

            params = new Array();
            params[0] = p;
        }

        return label.replace(/{\?}/g, function () {
            if (params[i] === undefined) {
                throw "Parameters list's length is less than count of placeholders"
            }
            return params[i++];
        });
    }
};

window.alert = function (text) {
    $("#alertDialog").html(text);
    showAlertDialog($("#alertDialog"), null, 500, 200);
};

/**
 * Javascript class extension function.
 *
 * @param Child child class function.
 * @param Parent parent class function.
 */
function extend(Child, Parent) {
    var F = function () {
    };

    F.prototype = Parent.prototype;

    Child.prototype = new F();
    Child.prototype.constructor = Child;
    Child.superclass = Parent.prototype;
}

function addDateValidation(element) {
    element.bind('keyup', checkDateValidity);
}

function isDateValid(element) {
    try {
        parseDate(element.val());
        return true;
    } catch (e) {
    }
    return false;
}

function parseDate(date) {
    return Date.parse(date, "yyyy-MM-dd");
}

function checkDateValidity() {
    if (isDateValid($(this))) {
        $(this).removeClass("error");
    } else {
        $(this).addClass("error");
    }
}
